package org.example.cloud.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.example.cloud.api.AccountFeignApi;
import org.example.cloud.api.StorageFeignApi;
import org.example.cloud.entities.Order;
import org.example.cloud.mapper.OrderMapper;
import org.example.cloud.service.OrderService;
import org.springframework.stereotype.Service;

/**
 * @author 宋孟林
 * @description
 * @date: 2025/4/12 8:03
 */
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private StorageFeignApi storageFeignApi;
    @Resource
    private AccountFeignApi accountFeignApi;

    @Override
    //给全局事务加上name属性因为可能别的地方也会有全局事务，rollback发生此种异常的时候回滚。加上全局事务的方法就是TM(Transaction Management)
    @GlobalTransactional(name = "sml-create-order", rollbackFor = Exception.class)
    public void create(Order order) {
        //全局事务id建议要加上
        String xid = RootContext.getXID();
        log.info("开始新建订单: " + "\t" + "全局事务id xid_order: " + xid);
        order.setStatus(0);
        int result = orderMapper.insert(order);
        Order orderFromDB = null;
        if (result > 0){
            //orderFromDB = orderMapper.selectById(order.getId());
            LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Order::getId, order.getId());
            orderFromDB = orderMapper.selectOne(wrapper);
            log.info("新建订单成功, orderFromDB info {}", orderFromDB);
            System.out.println();

            //这里要做好库存的数量减少和账户金额的扣减
            log.info("订单微服务开始调用库存api账户api，准备开始扣减库存数量和账户金额");
            storageFeignApi.decrease(orderFromDB.getProductId(), orderFromDB.getCount());
            accountFeignApi.decrease(orderFromDB.getUserId(), orderFromDB.getMoney());
            log.info("库存和账户金额业务完成");
            //上面两个方法成功后才更新订单状态为1
            orderFromDB.setStatus(1);

            /* 使用的是tk.mapper的通用构造方法来构建条件
            Example whereCondition = new Example(Order.class);
            Example.Criteria criteria = whereCondition.createCriteria();
            criteria.andEqualTo("userId", orderFromDB.getUserId());
            criteria.andEqualTo("status", 0);
            */

            //库存和金额更改成功之后将orderFromDB中已经更改的订单状态为1存储到数据库中。
            LambdaUpdateWrapper<Order> updateWrapper = new LambdaUpdateWrapper<>();
            //根据订单的用户id和订单状态为0来修改订单的其他非空字段
            updateWrapper.eq(Order::getUserId, orderFromDB.getUserId()).eq(Order::getStatus, 0);
            int updateResult = orderMapper.update(orderFromDB, updateWrapper);
            log.info("修改订单状态完成， " + "\t" + updateResult);
            log.info("orderFromDB info: {}", orderFromDB);
        }
        System.out.println();
        log.info("结束新建订单"  + "\t" + "xid_order: " + xid);
    }
}
